#include <stdio.h>
#include "hmi.h"

#include "freertos/FreeRTOS.h"
#include "freertos/semphr.h"

#include "esp_system.h"

#include "driver/gpio.h"
#include "driver/rmt.h"
#include "led_strip.h"

#define  LOCK_TIMEOUT   60000
static SemaphoreHandle_t beep_lock = NULL;
extern led_strip_t *strip;
extern int hex2dec(char *hex);
extern int c2i(char ch);
static void beep_init(void)
{
    /*beep gpio set*/
    gpio_set_level(CONFIG_HMI_BEEP_GPIO, 0);
    gpio_reset_pin(CONFIG_HMI_BEEP_GPIO);
    gpio_pad_select_gpio(CONFIG_HMI_BEEP_GPIO);
    gpio_set_direction(CONFIG_HMI_BEEP_GPIO, GPIO_MODE_OUTPUT);

    beep_lock = xSemaphoreCreateMutex();
    assert(beep_lock!=NULL);
}

void hmi_init(void)
{
    led_set_rgb_int();

    tts_init();

    beep_init();
}

void hmi_beep(uint32_t t_on, uint32_t t_off, uint8_t n)
{
    assert(beep_lock!=NULL);
    assert(xSemaphoreTakeRecursive(beep_lock,pdMS_TO_TICKS(LOCK_TIMEOUT))==pdTRUE);
    for(int i=0; i<n; i++)
    {
        hmi_beep_on();
        vTaskDelay(pdMS_TO_TICKS(t_on));
        hmi_beep_off();
        vTaskDelay(pdMS_TO_TICKS(t_off));
    }
    xSemaphoreGiveRecursive(beep_lock);
}

void hmi_beep_on(void)
{
    assert(beep_lock!=NULL);
    assert(xSemaphoreTakeRecursive(beep_lock,pdMS_TO_TICKS(LOCK_TIMEOUT))==pdTRUE);
    gpio_set_level(CONFIG_HMI_BEEP_GPIO, 1);
    xSemaphoreGiveRecursive(beep_lock);
}

void hmi_beep_off(void)
{
    assert(beep_lock!=NULL);
    assert(xSemaphoreTakeRecursive(beep_lock,pdMS_TO_TICKS(LOCK_TIMEOUT))==pdTRUE);
    gpio_set_level(CONFIG_HMI_BEEP_GPIO, 0);
    xSemaphoreGiveRecursive(beep_lock);
}

int hmi_tts_speak(const char text[], int len, int code)
{
    //TODO
    return 0;
}

void led_set(uint8_t num, char *string,uint32_t t_on) {
	int rgb = hex2dec(string);
	uint32_t green = 0x00ff00 & rgb;
	green = green >> 8;
	uint32_t red = 0xff0000 & rgb;
	red = red >> 16;
	uint32_t blue = 0x0000ff & rgb;
	//Write RGB values to strip driver
	ESP_ERROR_CHECK(strip->set_pixel(strip, 3-num, 0, 0, 0)); //Set RGB for a specific pixel
	ESP_ERROR_CHECK(strip->set_pixel(strip, 3-num, red, green, blue)); //Set RGB for a specific pixel
	ESP_ERROR_CHECK(strip->refresh(strip, 100)); //Refresh memory colors to LEDs
	if(t_on != 0){
		vTaskDelay(pdMS_TO_TICKS(t_on));
		ESP_ERROR_CHECK(strip->set_pixel(strip, 3-num, 0, 0, 0)); //Set RGB for a specific pixel
		ESP_ERROR_CHECK(strip->refresh(strip, 100)); //Refresh memory colors to LEDs
	}
}
